package com.bigknow.appstore.web.base.controller;

import com.bigknow.appstore.web.base.controller.entity.TreeNode;
import com.bigknow.appstore.web.base.entity.Permission;
import com.bigknow.appstore.web.base.entity.User;
import com.bigknow.appstore.web.base.service.impl.PermissionService;
import com.bigknow.appstore.web.console.app.Application;
import com.bigknow.appstore.web.console.app.ApplicationState;
import com.bigknow.appstore.web.console.service.IApplicationService;
import com.bigknow.appstore.web.framework.util.AuthenticateUserUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by 李科风 on 2016-06-03.
 */
@RestController
@RequestMapping(value = "/manager-index")
public class ManagerIndexController {

    @Autowired
    private PermissionService service;

    @Autowired
    private IApplicationService appService;

    /**
     * 构建菜单树
     * @param key
     * @return
     */
    @RequestMapping("/get-menu-tree")
    @ResponseBody
    public List<TreeNode> getMenuTree(String key) {
        List<TreeNode> nodes = new ArrayList<>();
        createMenuTreeNodeByPermission(nodes);
        if (StringUtils.isEmpty(key)) {
            return nodes;
        } else {
            try {
                key = URLDecoder.decode(key, "utf-8");
            } catch (UnsupportedEncodingException e) {
            }
            nodes = filterByKey(nodes, key);
        }
        return nodes;
    }

    static List<TreeNode> filterByKey(List<TreeNode> nodes, String key) {
        List<TreeNode> selectedNodes = nodes.stream().filter(n -> n.getName().toLowerCase().contains(key.toLowerCase())).collect(Collectors.toList());
        List<TreeNode> res = new ArrayList<>();
        while (!selectedNodes.isEmpty()) {
            selectedNodes.forEach(n -> {
                if (!res.contains(n)) {
                    res.add(n);
                    n.setOpen(true);
                }
            });
            selectedNodes = getParentNode(nodes, selectedNodes);
        }
        return res;
    }

    private static List<TreeNode> getParentNode(List<TreeNode> nodes, List<TreeNode> selectedNodes) {
        List<TreeNode> res = new ArrayList<>();
        selectedNodes.forEach(selNode -> {
            if (!StringUtils.isEmpty(selNode.getpId())) {
                nodes.forEach(p -> {
                    if (p.getId().equals(selNode.getpId())) {
                        res.add(p);
                    }
                });
            }
        });
        return res;
    }

    private void createMenuTreeNodeByPermission(List<TreeNode> nodes) {
        List<Permission> permissions = service.getMenuTreeByUserId(AuthenticateUserUtil.getUserId());
        //app store权限全部在 APPSTORE下面
        permissions.stream().filter(permission -> permission.getId().equals("APPSTORE"))
                .forEach(permission -> {
                    createTree(nodes, permission);
                });
    }

    private void createTree(List<TreeNode> nodes, Permission permission) {
        permission.getChildren().forEach(perm -> {
            TreeNode td = null;
            if (perm.getCode().equals("dataService")) {
                td = new TreeNode(perm.getCode(), perm.getParentCode(), perm.getName(),
                        perm.getPageUrl(), perm.getIconCss());
            } else if (perm.getCode().equals("appManager")) {
                td = new TreeNode(perm.getCode(), perm.getParentCode(), perm.getName(),
                        perm.getPageUrl(), perm.getIconCss());
                Application example = new Application();
                Subject subject = SecurityUtils.getSubject();
                User user = (User) subject.getPrincipal();
                example.setUserId(user.getId());

                TreeNode testApp = new TreeNode("testApp", perm.getCode(), "开发中",
                        "/console/app/list/TEST", "developing", true);
                example.setState(ApplicationState.TEST);
                List<Application> apps = appService.findWithFuzzy(example);
                for (Application app : apps) {
                    TreeNode appNode = new TreeNode(app.getId(), "testApp", app.getName(),
                            "/console/app/getApplication?id=" + app.getId(), "app");
                    nodes.add(appNode);
                }
                nodes.add(testApp);

                TreeNode applyingApp = new TreeNode("applyingApp", perm.getCode(), "申请中",
                        "/console/app/list/APPLYING", "applying", true);
                example.setState(ApplicationState.APPLYING);
                apps = appService.findWithFuzzy(example);
                for (Application app : apps) {
                    TreeNode appNode = new TreeNode(app.getId(), "applyingApp", app.getName(),
                            "/console/app/getApplication?id=" + app.getId(), "app");
                    nodes.add(appNode);
                }
                nodes.add(applyingApp);

                TreeNode publishedApp = new TreeNode("publishedApp", perm.getCode(), "已发布",
                        "/console/app/list/PUBLISHED", "published", true);
                example.setState(ApplicationState.PUBLISHED);
                apps = appService.findWithFuzzy(example);
                for (Application app : apps) {
                    TreeNode appNode = new TreeNode(app.getId(), "publishedApp", app.getName(),
                            "/console/app/getApplication?id=" + app.getId(), "app");
                    nodes.add(appNode);
                }
                nodes.add(publishedApp);

                TreeNode deprecatedApp = new TreeNode("deprecatedApp", perm.getCode(), "已过期",
                        "/console/app/list/DEPRECATED", "retired", true);
                example.setState(ApplicationState.DEPRECATED);
                apps = appService.findWithFuzzy(example);
                for (Application app : apps) {
                    TreeNode appNode = new TreeNode(app.getId(), "deprecatedApp", app.getName(),
                            "/console/app/getApplication?id=" + app.getId(), "app");
                    nodes.add(appNode);
                }
                nodes.add(deprecatedApp);
            } else {
                td = new TreeNode(perm.getCode(), perm.getParentCode(), perm.getName(),
                        perm.getPageUrl(), perm.getIconCss());
            }
            if (td != null) {
                td.setOpen(true);
                nodes.add(td);
                createTree(nodes, perm);
            }
        });
    }

}
